import io
from openai import OpenAI
import Logger_config

# 设置日志配置
logger = Logger_config.setup_logger()
class LLMProcess:

    def invokeLLM(model_name: str, api_key: str, base_url: str, max_tokens: int, temperature: float, stream: bool, messages):
        """
        调用大语言模型接口，生成对话响应。

        参数:
            model_name (str): 使用的模型名称。
            api_key (str): 认证所需的 API 密钥。
            base_url (str): API 的基础地址。
            max_tokens (int): 最多生成的 token 数量。
            temperature (float): 控制生成文本的随机性，值越低输出越确定。
            stream (bool): 是否启用流式输出。
            messages (list): 包含历史对话的消息列表。

        返回:
            response: OpenAI 接口返回的完整响应对象。

        异常:
            ValueError: 如果 `api_key` 或 `messages` 为空，抛出异常。
        """
        # 参数合法性校验
        if not api_key:
            raise ValueError("API密钥不能为空")
        if not messages or not isinstance(messages, list):
            raise ValueError("消息列表不能为空且必须是一个列表")

        try:
            # 初始化OpenAI客户端，使用指定的API密钥和基础URL
            client = OpenAI(api_key=api_key, base_url=base_url)

            # 调用大模型完成对话创建，设置参数如模型名称、消息列表、最大返回字符数、温度值以及是否流式输出
            response = client.chat.completions.create(
                model=model_name,
                messages=messages,
                max_tokens=max_tokens,  # 设置生成文本的最大长度
                temperature=temperature,  # 控制生成文本的随机性，值越低越确定
                stream=stream  # 流式输出设置
            )

            # 返回完整的响应对象
            return response

        except Exception as e:
            logger.error("调用LLM失败: %s", e)
            raise
    
    def getLLMTextResponse(model_name: str, api_key: str, base_url: str, max_tokens: int, temperature: float, stream: bool, messages) -> str:
        """
        调用大模型并获取文本响应。

        参数:
            model_name (str): 模型名称。
            api_key (str): API 密钥，用于认证。
            base_url (str): API 的基础 URL。
            max_tokens (int): 生成文本的最大长度。
            temperature (float): 控制生成文本的随机性，值越低越确定。
            stream (bool): 是否使用流式输出。
            messages (list): 包含对话历史的消息列表。

        返回:
            str: 大模型返回的完整响应文本。如果启用流式输出，则逐块拼接所有内容；否则直接提取完整响应。
        """
        try:
            # 调用invokeLLM方法
            response = LLMProcess.invokeLLM(model_name, api_key, base_url, max_tokens, temperature, stream, messages)

            # 如果启用流式输出
            if stream:
                full_response = ""  # 初始化一个空字符串用于拼接流式返回的内容
                # 遍历每个响应块
                for chunk in response:
                    # 检查当前块是否有内容
                    if chunk.choices and chunk.choices[0].delta and chunk.choices[0].delta.content:
                        content = chunk.choices[0].delta.content  # 提取当前块的文本内容
                        full_response += content  # 将当前块内容追加到完整响应中
            else:
                # 非流式输出时，直接提取第一个选择项的消息内容
                full_response = response.choices[0].message.content

            # 返回完整的模型响应文本
            return full_response
        except Exception as e:
            logger.error("调用大模型失败: %s", e)
            raise

    def onlineDeepSeek(messages):
        model_name="deepseek-chat"
        api_key="sk-b2cbd89d979b4c01849768e3714501b0"
        base_url="https://api.deepseek.com"
        max_tokens=8192
        temperature=0.7
        stream=False
        response = LLMProcess.invokeLLM(model_name,api_key,base_url,max_tokens,temperature,stream,messages)
        return response  
    def onlineQwenPlus(messages):
        model_name="qwen-plus"
        api_key="sk-a4e180ce088d4264886e4f8df871adb1"
        base_url="https://dashscope.aliyuncs.com/compatible-mode/v1"
        max_tokens=8192
        temperature=0.7
        stream=False
        response = LLMProcess.invokeLLM(model_name,api_key,base_url,max_tokens,temperature,stream,messages)
        return response  

    # 创建类实例并调用方法
if __name__ == "__main__":
    messages = [
            {"role": "system", "content": "/nothink 你是一个信息安全工程师，擅长处理软件安全问题，请根据用户的需求给出相应的建议。"},
            {"role": "user", "content": "请用中文讲个关于安全的笑话，500字以上"}
        ]
    full_response = LLMProcess.getLLMTextResponse("qwen3:32b","1111","http://10.0.83.199:9997/qwen3/v1",8192,0.7, True,  messages) 
    print("完整响应内容：", full_response)
